package com.detech.sbmh.base.page;

import com.detech.sbmh.base.hibernate.custom.CustomDAO;
import org.hibernate.Session;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.query.internal.QueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;

/**
 * 分页功能DAO类
 */
@Repository
public class PageDAO extends CustomDAO {
	
	/**
	 * 通用-HQL查询列表
	 */
	public Page queryDataList(Page page) {
		try {
			Session session = getCurrentSession();
			String hql = setHqlOrder(page); // 组装hql语句中的排序信息
			hql = hqlToHibernate5(hql);
			Query listQuery = session.createQuery(hql); // 列表数据查询

			String strQuery = listQuery.getQueryString(); // 取出查询语句
			String strCountQuery = null;	// 组装总记录数查询语句
			if(strQuery.trim().toLowerCase().startsWith("from")){
				strCountQuery = "select count(*) " + strQuery;
			}else{
				strCountQuery = "select count(*) from ( " + listQuery.getQueryString()+") allRecordsCounts";
			}
			Query countQuery = session.createQuery(strCountQuery); // 总记录数查询

			// 查询参数设置
			List paramList = page.getParamList();
			if (paramList != null && paramList.size() > 0) {
				for (int i = 0; i < paramList.size(); i++) {
					listQuery.setParameter(i, paramList.get(i));
					countQuery.setParameter(i, paramList.get(i));
				}
			}
			int totalrecord = 0; // 总记录数
			List countList = countQuery.list();// 执行总记录数查询
			if (countList != null && countList.size() > 0) {
				Long lnum = (Long) countList.get(0);// 得到总数
				totalrecord = lnum.intValue();
			}
			page.setTotalrecords(Integer.toString(totalrecord));// 设置总记录数
			page = getFenyeInfo(page);// 计算分页信息
			int eachpagecount = Integer.parseInt(page.getEachpagecount());// 每页显示
			int currpage = Integer.parseInt(page.getCurrpage());// 当前页
			if(totalrecord<=eachpagecount){
				currpage = 1;
				page.setCurrpage(currpage+"");
			}
			int intMin = eachpagecount * (currpage - 1); // 第1条记录的位置
			int intMax = eachpagecount; // 最大记录的位置

			listQuery.setFirstResult(intMin);
			listQuery.setMaxResults(intMax);
			if(page.getReturnType()!=null){
				listQuery.unwrap(QueryImpl.class).setResultTransformer(Transformers.aliasToBean(page.getReturnType()));
			}
			List list = listQuery.list();
			page.setBodyList(list);
			page.setHql("");
			page.setSql("");
			page.setColChangeList(null);
			page.setParamList(null);
		} catch (RuntimeException re) {
			throw re;
		}
		return page;
	}

	/**
	 * 通用-SQL查询列表
	 */
	public Page sqlQueryDataList(Page page) {
		try {
			Session session = getCurrentSession();
			String sql = setSqlOrder(page); // 组装hql语句中的排序信息
			NativeQuery listQuery = session.createNativeQuery(sql); // 列表数据查询

			String strQuery = listQuery.getQueryString(); // 取出查询条件
			String strCountQuery = "select count(*) from( " + listQuery.getQueryString()+") allRecordsCounts"; // 组装总记录数查询语句
			NativeQuery countQuery = session.createNativeQuery(strCountQuery); // 总记录数查询

			// 查询参数设置
			List paramList = page.getParamList();
			if (paramList != null && paramList.size() > 0) {
				for (int i = 1; i <= paramList.size(); i++) {
					listQuery.setParameter(i, paramList.get(i));
					countQuery.setParameter(i, paramList.get(i));
				}
			}
			// 进行数据类型转换参数设置
			List<SqlType> colChangeList = page.getColChangeList();
			if (colChangeList != null && colChangeList.size() > 0) {
				for (int i = 0; i < colChangeList.size(); i++) {
					SqlType colType = colChangeList.get(i);
					if (colType != null) {
						listQuery.addScalar(colType.getColname(), colType.getColtype());
					}
				}
			}
			int totalrecord = 0; // 总记录数
			List countList = countQuery.list();// 执行总记录数查询
			if (countList != null && countList.size() > 0) {
				try{
					BigDecimal lnum = (BigDecimal) countList.get(0);// 得到总数
					totalrecord = lnum.intValue();
				}catch (Exception e) {
					try{
						totalrecord = ((Integer) countList.get(0)).intValue();// 得到总数
					}catch (Exception e2) {
						totalrecord = ((BigInteger) countList.get(0)).intValue();// 得到总数
					}
				}
			}
			page.setTotalrecords(Integer.toString(totalrecord));// 设置总记录数
			page = getFenyeInfo(page);// 计算分页信息
			int eachpagecount = Integer.parseInt(page.getEachpagecount());// 每页显示
			int currpage = Integer.parseInt(page.getCurrpage());// 当前页
			if(totalrecord<=eachpagecount){
				currpage = 1;
				page.setCurrpage(currpage+"");
			}
			int intMin = eachpagecount * (currpage - 1); // 第1条记录的位置
			int intMax = eachpagecount; // 最大记录的位置

			listQuery.setFirstResult(intMin);
			listQuery.setMaxResults(intMax);
			if(page.getReturnType()==null) {
				listQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			}else{
				listQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(page.getReturnType()));
			}
			List list = listQuery.list();
			page.setBodyList(list);
			page.setHql("");
			page.setSql("");
			page.setColChangeList(null);
			page.setParamList(null);
		} catch (RuntimeException re) {
			throw re;
		}
		return page;
	}

	/**
	 * 计算总页数,上一页,下一页
	 */
	public Page getFenyeInfo(Page page) {
		String strTotalrecords = page.getTotalrecords();
		String strTotalpage = page.getTotalpage();
		String strEachpagecount = page.getEachpagecount();
		int totalrecord = 0;// 总记录数
		int totalpage = 0;
		if (strTotalpage != null && !"".equals(strTotalpage))
			totalpage = Integer.parseInt(strTotalpage);

		// 取总记录数
		if (strTotalrecords != null && !"".equals(strTotalrecords))
			totalrecord = Integer.parseInt(strTotalrecords);
		// 计算总页数
		if (totalrecord % Integer.parseInt(strEachpagecount) == 0) { // 如果可以整除,刚好够页数
			totalpage = totalrecord / Integer.parseInt(strEachpagecount);
			if (totalpage == 0) {
				totalpage = 1;
			}
		} else {// 否则加一页
			totalpage = (totalrecord / Integer.parseInt(strEachpagecount)) + 1;
		}
		page.setTotalpage(Integer.toString(totalpage));
		return page;
	}

	/**
	 * 判断一个字符在另一个字符中出现的次数
	 * @param str	基础字符
	 * @param cmp	比较字符
	 * @return int
	 */
	public int strAppareCountOne(String str,String cmp){
		int count = 0;
		if(str!=null && cmp!=null){
			String strTemp = str;
			while(strTemp!=null && strTemp.length()>0){
				String strSub = strTemp.substring(0, 1);
				if(strSub.equals(cmp)){
					count = count + 1;
				}
				if(strTemp.length()>1){
					strTemp = strTemp.substring(1,strTemp.length());
				}else{
					strTemp = null;
				}
			}
		}
		return count;
	}

	/**
	 * 设置HQL查询排序字段
	 * @param page
	 * @return String
	 */
	private String setHqlOrder(Page page) {
		String hql = page.getHql();
		String strOrdercol = page.getOrderByColumn();
		String strOrderwise = page.getOrderWise();
		if (strOrdercol != null && !"".equals(strOrdercol.trim())) {
			hql = hql + " order by " + strOrdercol;
			if (strOrderwise != null && !"".equals(strOrderwise.trim())) {
				hql = hql + " " + strOrderwise;
			}
		}
		return hql;
	}

	/**
	 * 设置SQL查询排序字段
	 * @param page
	 * @return String
	 */
	private String setSqlOrder(Page page) {
		String sql = page.getSql();
		String strOrdercol = page.getOrderByColumn();
		String strOrderwise = page.getOrderWise();
		if (strOrdercol != null && !"".equals(strOrdercol.trim())) {
			sql = sql + " order by " + strOrdercol;
			if (strOrderwise != null && !"".equals(strOrderwise.trim())) {
				sql = sql + " " + strOrderwise;
			}
		}
		return sql;
	}

	public String hqlToHibernate5(String hql) {
		String hqlTmp = "";
		int firstPos = -1;
		int index = hql.indexOf("?",firstPos);
		if(index < 0){
			return hql;
		}
		int count = 0;
		while (index>=0){
			hqlTmp = hqlTmp + hql.substring(firstPos+1,index) + "?" + count;
			count++;
			firstPos = index;
			index = hql.indexOf("?",index + 1);
		}
		return hqlTmp;
	}
}
